﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Kinect;
using System.IO;
using System.Collections;

namespace GestureSaver
{
    public class GestureDB : IEnumerable
    {
        Dictionary<GestureType, List<Gesture>> data;

        public GestureDB()
        {
            data = new Dictionary<GestureType, List<Gesture>>();
        }

        public GestureDB(string fileName)
        {
            data = new Dictionary<GestureType, List<Gesture>>();

            string[] directories = Directory.GetDirectories(fileName);

            foreach (var directory in directories)
            {
                List<Gesture> samples = new List<Gesture>();

                string[] files = Directory.GetFiles(directory);

                foreach (var file in files)
                {
                    Gesture g = new Gesture(file);
                    samples.Add(g);
                }

                data.Add(samples[0].gestureType, samples);
            }
        }

        public void AddGesture(Gesture g)
        {
            if (!data.ContainsKey(g.gestureType))
            {
                List<Gesture> emptyList = new List<Gesture>();
                data.Add(g.gestureType, emptyList);
            }

            data[g.gestureType].Add(g);
        }

        public List<Gesture> this[GestureType gestureType]
        {
            get
            {
                return data[gestureType];
            }
            set
            {
                data[gestureType] = value;
            }
        }

        public List<Gesture> this[int position]
        {
            get
            {
                return data.ElementAt(position).Value;            
            }
            set
            {
                data[(GestureType)position] = value;
            }
        }

        public void Save(string directoryPath)
        {
            if (Directory.Exists(directoryPath))
            {
                Directory.Delete(directoryPath, true);
            }

            Directory.CreateDirectory(directoryPath);

            foreach (List<Gesture> item in this)
            {
                string tempPath = directoryPath + @"\" + item[0].gestureType.ToString();

                Directory.CreateDirectory(tempPath);

                for (int i = 0; i < item.Count; i++)
                {
                    string temp = tempPath + @"\" + item[i].gestureType + "_" + i.ToString("D3") + ".txt";
                    item[i].SaveToFile(temp);
                }
            }
        }

        public int TotalSampleCount
        {
            get
            {
                int sum = 0;

                foreach (List<Gesture> item in this)
                {
                    sum += item.Count;
                }

                return sum;
            }
        }

        public int TotalClassCount 
        {
            get
            {
                return data.Count;              
            }        
        }

        public IEnumerator GetEnumerator()
        {
            return new GestureDBEnumerator(this);
        }

        private class GestureDBEnumerator : IEnumerator
        {
            private int position = -1;
            private GestureDB instance;

            public GestureDBEnumerator(GestureDB inst)
            {
                this.instance = inst;
            }

            public object Current
            {
                get
                {
                    try
                    {
                        return instance.data.ElementAt(position).Value;
                    }
                    catch (IndexOutOfRangeException)
                    {
                        throw new InvalidOperationException();
                    }
                }
            }

            public bool MoveNext()
            {
                position++;
                
                if (position == instance.data.Count)
                {
                    return false;
                }
                return true;              
            }

            public void Reset()
            {
                position = -1;
            }
        }
    }
}
